/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.common.base.controller;

import com.alibaba.fastjson2.JSONObject;
import com.je.common.base.DynaBean;
import com.je.common.base.JsonAssist;
import com.je.common.base.mapper.query.Query;
import com.je.common.base.mvc.AbstractPlatformController;
import com.je.common.base.mvc.BaseMethodArgument;
import com.je.common.base.result.BaseRespResult;
import com.je.common.base.result.DirectJsonResult;
import com.je.common.base.service.CommonTreeService;
import com.je.common.base.service.rpc.BeanService;
import com.je.common.base.util.ArrayUtils;
import com.je.common.base.util.StringUtil;
import com.je.common.base.util.TreeUtil;
import com.je.core.entity.extjs.JSONTreeNode;
import com.je.ibatis.extension.conditions.ConditionsWrapper;
import com.je.ibatis.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping(value = "/je/common/tree")
public class CommonTreeController extends AbstractPlatformController {

    @Autowired
    private BeanService beanService;
    @Autowired
    private CommonTreeService commonTreeService;

    @Override
    @RequestMapping(value = "/load", method = RequestMethod.POST, produces = "application/json; charset=utf-8")
    public BaseRespResult load(BaseMethodArgument param, HttpServletRequest request) {
        if (param.getLimit() == 0) {
            param.setLimit(-1);
        }
        //分页对象
        Page page = new Page<>(param.getPage(), param.getLimit());
        String funcCode = param.getFuncCode();
        //构建查询条件
        ConditionsWrapper wrapper = manager.buildWrapper(param, request);
        List<Map<String, Object>> list = metaService.load(funcCode, page, wrapper);
        page.setRecords(list);
        return BaseRespResult.successResultPage(page.getRecords(), (long) page.getTotal());
    }

    @Override
    @RequestMapping(
            value = {"/doSave"},
            method = {RequestMethod.POST},
            produces = {"application/json; charset=utf-8"}
    )
    public BaseRespResult doSave(BaseMethodArgument param, HttpServletRequest request) {
        DynaBean dynaBean = (DynaBean) request.getAttribute("dynaBean");
        String codeGenFieldInfo = this.getStringParameter(request, "codeGenFieldInfo");
        String funcCode = getStringParameter(request, "funcCode");
        String batchFilesFields = getStringParameter(request, "batchFilesFields");
        String uploadableFields = getStringParameter(request, "uploadableFields");
        commonService.buildProductInfo(dynaBean);
        DynaBean savedBean;
        if (commonService.checkFuncMoreRoot(funcCode)) {
            savedBean = commonTreeService.doMoreRootSave(funcCode, dynaBean, codeGenFieldInfo, batchFilesFields, uploadableFields);
        } else {
            savedBean = commonTreeService.doSingleSave(funcCode, dynaBean, codeGenFieldInfo, batchFilesFields, uploadableFields);
        }
        JSONTreeNode node = commonTreeService.buildSingleTreeNode(savedBean);
        Map<String, Object> result = new HashMap<>();
        result.put("dynaBean", savedBean.getValues());
        result.put("node", node);
        node.setBean(savedBean.getValues());
        return BaseRespResult.successResult(result);
    }

    @Override
    @RequestMapping(
            value = {"/doUpdate"},
            method = {RequestMethod.POST},
            produces = {"application/json; charset=utf-8"}
    )
    public BaseRespResult doUpdate(BaseMethodArgument param, HttpServletRequest request) {
        DynaBean updateBean = manager.doUpdate(param, request);
        JSONTreeNode node = commonTreeService.buildSingleTreeNode(updateBean);
        Map<String, Object> result = new HashMap<>();
        result.put("dynaBean", updateBean.getValues());
        result.put("node", node);
        node.setBean(updateBean.getValues());
        return BaseRespResult.successResult(result);
    }

    @Override
    @RequestMapping(value = "/doUpdateList", method = RequestMethod.POST, produces = "application/json; charset=utf-8")
    public BaseRespResult doUpdateList(BaseMethodArgument param, HttpServletRequest request) {
        String funcType = getStringParameter(request, "funcType");
        String funcCode = getStringParameter(request, "funcCode");
        String subFuncForeignKey = getStringParameter(request, "subFuncForeignKey");
        String codeGenFieldInfo = param.getCodeGenFieldInfo();
        List<DynaBean> list;
        //多根树或单根树处理
        if (commonService.checkFuncMoreRoot(funcCode)) {
            list = commonTreeService.doMoreRootUpdateList(param.getTableCode(), param.getStrData(), funcType, funcCode, codeGenFieldInfo, subFuncForeignKey);
        } else {
            list = commonTreeService.doSingleUpdateList(param.getTableCode(), param.getStrData(), funcType, funcCode, codeGenFieldInfo);
        }
        List<Object> returnList = new ArrayList<>();
        List<JSONTreeNode> nodeList = new ArrayList<>();
        for (DynaBean dynaBean : list) {
            JSONTreeNode jsonTreeNode =commonTreeService.buildSingleTreeNode(dynaBean);
            jsonTreeNode.setBean(dynaBean.getValues());
            nodeList.add(jsonTreeNode);
            returnList.add(dynaBean.getValues());
        }
        Map<String, Object> result = new HashMap<>();
        result.put("dynaBeans", returnList);
        result.put("nodes", nodeList);
        return BaseRespResult.successResult(result);
    }

    @Override
    @RequestMapping(
            value = {"/doRemove"},
            method = {RequestMethod.POST},
            produces = {"application/json; charset=utf-8"}
    )
    public BaseRespResult doRemove(BaseMethodArgument param, HttpServletRequest request) {
        return super.doRemove(param, request);
    }

    @RequestMapping(value = "/loadTree", method = RequestMethod.POST, produces = "application/json; charset=utf-8")
    public BaseRespResult loadTree(BaseMethodArgument param, HttpServletRequest request) {
        JSONTreeNode tree = manager.getTree(param, request);
        if (tree != null) {
            return BaseRespResult.successResult(DirectJsonResult.buildObjectResult(tree));
        } else {
            return BaseRespResult.successResult(DirectJsonResult.buildObjectResult("{}"));
        }
    }

    @RequestMapping(value = "/getTree", method = RequestMethod.POST, produces = "application/json; charset=utf-8")
    public BaseRespResult getTree(BaseMethodArgument param, HttpServletRequest request) {
        JSONTreeNode tree = manager.getTree(param, request);
        if (tree != null) {
            return BaseRespResult.successResult(DirectJsonResult.buildObjectResult(tree));
        } else {
            return BaseRespResult.successResult(DirectJsonResult.buildObjectResult("{}"));
        }
    }

    @RequestMapping(value = "/loadGridTree", method = RequestMethod.POST, produces = "application/json; charset=utf-8")
    public BaseRespResult loadGridTree(BaseMethodArgument param, HttpServletRequest request) {
        JSONObject result = manager.loadGridTree(param, request);
        JSONObject jsonObject = DirectJsonResult.buildObjectResult(result);
        return BaseRespResult.successResult(jsonObject);
    }

    /**
     * 查询表数据   后续按照资源表树形类型构建成 树形节点
     */
    @RequestMapping(value = "/loadTreeData", method = RequestMethod.POST)
    public JSONObject loadTreeData(BaseMethodArgument param, HttpServletRequest request) {
        int limit = param.getLimit();
        int page = param.getPage();
        String tableCode = param.getTableCode();
        Boolean onlyItem = param.getOnlyItem();
        String excludes = param.getExcludes();
        JsonAssist jsonAssist = JsonAssist.getInstance();
        String strData = null;

        List<DynaBean> list;
        Query query = param.buildQuery();
        ConditionsWrapper wrapper = query.buildWrapper().apply(!query.getOrder().isEmpty(), " ORDER BY " + query.buildOrder());
        //查询  如果limit为-1表示不分页，查询全部数据
        if (limit == -1) {
            list = metaService.select(param.getTableCode(), wrapper);
        } else {
            list = metaService.select(param.getTableCode(), page, limit, wrapper);
        }
        JSONTreeNode rootNode = TreeUtil.buildRootNode();
        String configInfo = getStringParameter(request, "configInfo");
        JSONTreeNode template = new JSONTreeNode();
        if (StringUtil.isNotEmpty(configInfo)) {
            JSONObject configObj = JSONObject.parseObject(configInfo);
            if (configObj.containsKey("id")) {
                template.setId(configObj.getString("id"));
            }
            if (configObj.containsKey("text")) {
                template.setText(configObj.getString("text"));
            }
            if (configObj.containsKey("code")) {
                template.setCode(configObj.getString("code"));
            }
            if (configObj.containsKey("nodeInfo")) {
                template.setNodeInfo(configObj.getString("nodeInfo"));
            }
            if (configObj.containsKey("nodeInfoType")) {
                template.setNodeInfoType(configObj.getString("nodeInfoType"));
            }
            if (configObj.containsKey("icon")) {
                template.setIcon(configObj.getString("icon"));
            }
            if (configObj.containsKey("disabled")) {
                template.setDisabled(configObj.getString("disabled"));
            }
            if (configObj.containsKey("description")) {
                template.setCode(configObj.getString("description"));
            }
            if (configObj.containsKey("orderIndex")) {
                template.setOrderIndex(configObj.getString("orderIndex"));
            }
        } else {
            DynaBean table = beanService.getResourceTable(tableCode);
            List<DynaBean> columns = (List<DynaBean>) table.get(BeanService.KEY_TABLE_COLUMNS);
            template = beanService.buildJSONTreeNodeTemplate(columns);
        }
        for (DynaBean bean : list) {
            JSONTreeNode node = new JSONTreeNode();
            node.setId(bean.getPkValue());
            node.setParent(rootNode.getId());
            node.setLeaf(true);
            if (StringUtil.isNotEmpty(template.getText())) {
                node.setText(bean.getStr(template.getText()));
            }
            if (StringUtil.isNotEmpty(template.getCode())) {
                node.setCode(bean.getStr(template.getCode()));
            }
            //节点信息
            if (StringUtil.isNotEmpty(template.getNodeInfo())) {
                node.setNodeInfo(bean.getStr(template.getNodeInfo()));
            }
            //节点信息类型
            if (StringUtil.isNotEmpty(template.getNodeInfoType())) {
                node.setNodeInfoType(bean.getStr(template.getNodeInfoType()));
            }
            //图标样式
            if (StringUtil.isNotEmpty(template.getIcon())) {
                node.setIcon(bean.getStr(template.getIcon()));
            }
            //是否禁用
            if (StringUtil.isNotEmpty(template.getDisabled())) {
                node.setDisabled(bean.getStr(template.getDisabled()));
            } else {
                node.setDisabled("0");
            }
            //描述
            if (StringUtil.isNotEmpty(template.getDescription())) {
                node.setDescription(bean.getStr(template.getDescription()));
            }
            //排序
            if (StringUtil.isNotEmpty(template.getOrderIndex())) {
                node.setOrderIndex(bean.getStr(template.getOrderIndex()) + "");
            }
            node.setBean(bean.getValues());
            rootNode.getChildren().add(node);
        }
        if (onlyItem) {
            strData = jsonAssist.buildListPageJson(new Long(0), rootNode.getChildren(), excludes.split(ArrayUtils.SPLIT), false);
        } else {
            strData = jsonAssist.buildModelJson(rootNode, excludes.split(","));
        }
        return DirectJsonResult.buildObjectResult(strData);
    }


    @RequestMapping(value = "/getTreeListBySearchName", method = RequestMethod.POST)
    public BaseRespResult getTreeListBySearchName(BaseMethodArgument param, HttpServletRequest request) {
        //暂时保留，后面会去掉tableCode
        String funcCode = param.getFuncCode();
        String tableCode = param.getTableCode();
        String searchName = getStringParameter(request, "searchName");
        String ddCode = getStringParameter(request, "DICTIONARY_DDCODE");
        return BaseRespResult.successResult(commonTreeService.getTreeListBySearchName(tableCode, searchName, ddCode));
    }
}
